import * as React from "react";
import * as monacoGlobal from "monaco-editor";
import SplitPane from "react-split-pane";

import { EditorPane } from "./EditorPane";
import { GraphPane } from "./GraphPane";
import { SupportedFormat, SupportedEngine } from "../rendering";
import { getSplitConfig, saveSplitConfig } from "../config";

type ErrorList = monacoGlobal.editor.IMarkerData[];

interface Props {
	initialSource: string;
	format: SupportedFormat;
	engine: SupportedEngine;
	onSourceChange?(source: string): void;
}


// 在 State 类型中添加 changeValue、oldValue 和 stepNum
type State = SourceState | ErroredState;
interface SourceState {
	dotSrc: string;
	errors: undefined;
	lastKnownGoodSrc: undefined;
	oneValue: string;
	twoValue: string;
	oldValue: any;
	stepNum: number;
}
interface ErroredState {
	dotSrc: undefined;
	errors: ErrorList;
	lastKnownGoodSrc?: string;
	oneValue: string;
	twoValue: string;
	oldValue: any;
	stepNum: number;
}

const createSourceState = (dotSrc: string): SourceState => ({
	dotSrc,
	errors: undefined,
	lastKnownGoodSrc: undefined,
	oneValue: '',
	twoValue: '',
	oldValue: undefined,
	stepNum: 0
});
const createErroredState = (
	errors: ErrorList,
	lastKnownGoodSrc?: string
): ErroredState => ({
	dotSrc: undefined,
	errors,
	lastKnownGoodSrc,
	oneValue: '',
	twoValue: '',
	oldValue: undefined,
	stepNum: 0
});

export default class SplitEditor extends React.Component<Props, State> {
	private editorPaneRef: React.RefObject<EditorPane> = React.createRef();

	constructor(props: Props) {
		super(props);
		const p = this.props;

		this.state = createSourceState(p.initialSource);
		if (p.onSourceChange) {
			p.onSourceChange(this.state.dotSrc);
		}
	}

	public loadDotSource(dotSrc: string) {
		const editor = this.editorPaneRef.current;
		if (editor) {
			editor.loadValue(dotSrc);
		}
	}

	dotSourceChanged = (dotSrc: string): void => {
		const p = this.props;
		if (p.onSourceChange) {
			p.onSourceChange(dotSrc);
		}

		this.setState(createSourceState(dotSrc));
	}

	dotSourceErrored = (errors: ErrorList): void => {
		this.setState(prevState => {
			const lastKnownGoodSrc = prevState.dotSrc || prevState.lastKnownGoodSrc;
			return createErroredState(errors, lastKnownGoodSrc);
		});
	}

	private getDotSrcToRender() {
		const s = this.state;

		return !!s.dotSrc ? s.dotSrc : s.lastKnownGoodSrc || "";
	}

	public componentDidMount() {
		const that = this;

		setTimeout(() => {
			const nodeElements = document.querySelectorAll('.node');

			nodeElements.forEach((node) => {
				node.addEventListener('click', () => {
					const { oneValue, twoValue, oldValue, stepNum } = that.state;
					if (stepNum === 2) {
						that.setState({ oneValue: '' })
						that.setState({ twoValue: '' })
						that.setState({stepNum: 0})
					}
					debugger

					const titleElement = node.querySelector('title');
					if (titleElement) {
						const titleValue:any = titleElement.textContent;
						if (titleValue !== oldValue) {
							if (stepNum === 0) {
								if (typeof titleValue === "string") {
									that.setState({ oneValue: titleValue })
									that.setState({ oldValue: titleValue })
									that.setState({stepNum: 1})
								}
								alert('获取初始线成功');
							} else if (stepNum === 1) {
								if (typeof titleValue === "string") {
									that.setState({ twoValue: titleValue })
									that.setState({ oldValue: titleValue })
									that.setState({stepNum: 2})
								}

								let _dotSrc:any = that.state.dotSrc;
								const colorRegex = /color="([^"]+)"/;
								const match = _dotSrc.match(colorRegex);
								let color;
								if (match) {
									color = match[1];
								} else {
									color = '#000000';
								}

								const newEdge = `\t${oneValue} -- ${twoValue} [color="${color}"]\n`;
								_dotSrc = _dotSrc.slice(0, -2) + newEdge + _dotSrc.slice(-2);

								alert('获取终止线成功');
								that.setState(createSourceState(_dotSrc));
								return;
							}
						}
						console.log(`点击节点获取的 title 值为: ${titleValue}`);
					}

				});
			});
		}, 1000);
	}

	public render() {
		const s = this.state;
		const p = this.props;
		const that = this;

		const isErrored = s.errors && s.errors.length > 0;
		const dotSrc = this.getDotSrcToRender();

		console.log('dotSrcsssss');
		console.log(dotSrc);

		const messageHandle = function (e: any) {
			console.log('接受到的信息是：' + e.data);
			let dotSrc22 = encodeURIComponent(`"# Place the cursor inside "graph" to get some refactoring options

            graph {

                # To refactor nodes, place the cursor left to a node name
                a -- b
                a -- c;
                a -- d;
                a -- b;
                a -- ec;

                # Hover over color names to get a color picker
                b -- b [color=blue]
                b -- d [color="#ff0000"];

                # Get completion when assigning a shape or color
                b [shape=box, color=yellow];

                a; # You can remove optional ; by placing the cursor left to a semicolon
            }
            "`);
			that.setState(createSourceState(dotSrc));
		};

		if (window.addEventListener) {
			window.addEventListener("message", messageHandle, false);
		}

		console.log('this.state.dotSrc', dotSrc);
		console.log('this.state.dotSrc', s.dotSrc);

		const graphPaneClass = isErrored ? "errored" : "successful";

		return (
			<SplitPane
				split="vertical"
				minSize={50}
				defaultSize={getSplitConfig() || "50%"}
				onChange={size => saveSplitConfig(size)}
			>
				<EditorPane
					ref={this.editorPaneRef}
					defaultValue={s.dotSrc}
					onChangeValue={this.dotSourceChanged}
					onValueError={this.dotSourceErrored}
				/>
				<GraphPane
					className={"graph-container " + graphPaneClass}
					dotSrc={dotSrc}
					engine={p.engine}
					format={p.format}
				/>
			</SplitPane>
		);
	}
}
